package com.example.cloud.controller.system;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.cloud.clients.AuthFeignClient;
import com.example.cloud.constants.StateConstants;
import com.example.cloud.controller.common.BaseController;
import com.example.cloud.model.dto.QueryModel;
import com.example.cloud.model.dto.Result;
import com.example.cloud.model.system.Menu;
import com.example.cloud.model.system.Organ;
import com.example.cloud.model.system.Role;
import com.example.cloud.model.system.User;
import com.example.cloud.service.system.MenuService;
import com.example.cloud.service.system.RoleService;
import com.example.cloud.service.system.UserService;
import com.example.cloud.socket.WebSocketServer;
import com.example.cloud.utils.RequestUtil;
import com.example.cloud.utils.ResultUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

import static java.util.stream.Collectors.toList;

/**
 * Created by wangtao on 2018/1/26.
 */
@RestController
public class UserController extends BaseController {

    private Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private AuthFeignClient authFeignClient;

    @PostMapping("/search")
    public Result search(@RequestBody QueryModel model) {
        Result result = this.singleQuery(model, User.class);
        JSONArray datas = (JSONArray)result.getData();
        for (Object data : datas) {
            JSONObject json = (JSONObject)data;
            Long id = json.getLong("id");
            if(WebSocketServer.clientMaps.containsKey(id)){
                json.put("onlineStatus", 1);
            }else{
                json.put("onlineStatus", 0);
            }
        }
        return result;
    }

    @GetMapping("/findAll")
    public Result findByAll() {
        return ResultUtil.success(userService.findByAccountIdFromCache());
    }

    @GetMapping("/findById")
    public User findById(@RequestParam("id") Long id) {
        return userService.findOneFromCache(id);
    }

    @GetMapping("/findByJob/{jobType}")
    public Result findByJob(@PathVariable int jobType) {
        return ResultUtil.success(userService.findByJobFromCache(jobType));
    }

    @GetMapping("/findByDepartmentId/{id}")
    public Result findByDepartmentId(@PathVariable Long id){
        return ResultUtil.success(userService.findByDepartmentId(id));
    }

    @GetMapping("/loadUser")
    public Result loadUser() {
        List<Long> ids = new ArrayList<>();
        for (Organ organ : RequestUtil.getLoginUser().getOrgans()) {
            ids.add(organ.getId());
        }
        return ResultUtil.success(userService.findHealthcareFromCache(ids));
    }

    @PostMapping("/checkLogin")
    public Result checkLogin(@RequestParam("username") String username, @RequestParam("password") String password) throws Exception {
        User user = userService.findUserByNameFromCache(username);
        if (user == null) {
            return ResultUtil.fail("用户名错误");
        }
        if (!password.equals(user.getPassword())) {
            return ResultUtil.fail("密码错误");
        }
        if (user.getStatus() == StateConstants.STATUS_FREEZE) {
            return ResultUtil.fail("用户已被冻结");
        }
        // 保存用户登录信息
        RequestUtil.setLoginUser(user);
        return ResultUtil.success(user);
    }

    @PostMapping("/saveOrUpdate")
    public void saveOrUpdate(@RequestBody User user) {
        if (user.getId() == null) {
            user.setPassword(DigestUtils.md5Hex(user.getPassword()));
            User loginUser = RequestUtil.getLoginUser();
            user.setAccountId(loginUser.getAccountId());
            user.setOrganId(loginUser.getOrganId());
            user.setOrganName(loginUser.getOrganName());
        }
        user.setRoles(null);
        user.setOrgans(null);
        userService.doSave(user);
    }

    @GetMapping("/menus")
    public JSONArray menus(@RequestParam("userId") Long userId) {
        JSONArray jsonArray = new JSONArray();
        List<Menu> menus = new ArrayList<Menu>();
        User user = userService.findOneFromCache(userId);
        if (user.getIsAdmin() == 1) {
            // 管理员
            menus = menuService.findAllByMenuFromCache();
        } else {
            // 非管理员
            for (Role userRole : user.getRoles()) {
                Role role = roleService.findOneFromCache(userRole.getId());
                for (Menu roleMenu : role.getMenus()) {
                    if (!menus.contains(roleMenu) && roleMenu.getIsShow() == 1) {
                        menus.add(roleMenu);
                    }
                }
            }
        }
        if (!menus.isEmpty()) {
            jsonArray = menuService.createMenuTree(menus, 1);
        }
        return jsonArray;
    }

    @GetMapping("/allButtons")
    public Result allButtons(@RequestParam("userId") Long userId){
        List<Menu> buttons = new ArrayList<>();
        User user = userService.findOneFromCache(userId);
        if(user.getIsAdmin() == 1){
            buttons = menuService.findAllByButtonFromCache();
        }else{
            for (Role userRole : user.getRoles()) {
                Role role = roleService.findOneFromCache(userRole.getId());
                for (Menu roleButton : role.getMenus()) {
                    if(!buttons.contains(roleButton) && roleButton.getType() == StateConstants.MENU_TYPE_BUTTON){
                        buttons.add(roleButton);
                    }
                }
            }
        }
        buttons.sort((b1, b2) -> b1.getSort() > b2.getSort() ? 1 : -1);
        return ResultUtil.success(buttons);
    }

    @GetMapping("/buttons/{menuId}")
    public Result buttons(@PathVariable Long menuId) {
        List<Menu> buttons = new ArrayList<Menu>();
        User user = RequestUtil.getLoginUser();
        if (user.getIsAdmin() == 1) {
            // 管理员
            buttons = menuService.findAllByButtonFromCache();
        } else {
            // 非管理员
            for (Role userRole : user.getRoles()) {
                buttons = roleService.findOneFromCache(userRole.getId()).getMenus().stream().filter(menu -> menu.getType() == StateConstants.MENU_TYPE_BUTTON
                        && menu.getParentId() != null && menuId.equals(menu.getParentId())).collect(toList());
            }
        }
        buttons.sort((b1, b2) -> b1.getSort() > b2.getSort() ? 1 : -1);
        return ResultUtil.success(buttons);
    }

    @GetMapping("/getWorkUser")
    public Result getWorkUser() {
        return ResultUtil.success(userService.findUserByLogis());
    }

    @PostMapping("/freeze")
    public void freeze(@RequestBody List<Long> ids) {
        userService.doFreeze(ids);
    }

    @PostMapping("/use")
    public void use(@RequestBody List<Long> ids) {
        userService.doUse(ids);
    }

    @PostMapping("/delete")
    public void delete(@RequestBody List<Long> ids) {
        userService.doDelete(ids);
    }
}
